﻿using Ewell.BizComponent.Charge.Model;
using Ewell.BizComponent.Service.Model.Insur.Response;
using Ewell.BizComponent.Service.Server;
using Ewell.Interface.Accounting.Common.Model.Request;
using Ewell.Interface.Accounting.Common.Model.Response;
using Ewell.Interface.Common.Model.Common;
using Ewell.Interface.Common.Model.GateWay.Dto.Dict;
using Ewell.Interface.Common.Model.GateWay.GateWayUriInfo;
using Ewell.Interface.Common.Utils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using static Ewell.BizComponent.Charge.UI.VM.CashierStepVm;
using OutPayResponse = Ewell.BizComponent.Service.Model.Insur.Response.OutPayResponse;

namespace Ewell.BizComponent.Charge.UI.VM
{
    /// <summary>
    /// 预算
    /// </summary>
    public class PreCashierVm : CashierBaseVm
    {
        /// <summary>
        /// 预算结果通知
        /// </summary>
        public event EventHandler<CashierContext> NoticeChargeResult;
        /// <summary>
        /// 取消预算通知
        /// </summary>
        public event EventHandler<CashierContext> NoticeChargeCancel;
        public override StepLoading stepLoading => new StepLoading(context =>
        {
            this.context = context;

            this.context.cashierMainVm.currentStep.StepState = FunnyArts.Wpf.ControlLibrary.Model.StepStatus.Running;

            ChooseInsurTypeVm chooseInsurTypeVm=new ChooseInsurTypeVm();
            chooseInsurTypeVm.context = context;
            //查询医保费别
            DictPatientTypeDubboService dictPatientTypeDubboService=new DictPatientTypeDubboService();
            var gateWayResult=dictPatientTypeDubboService.queryPagePatientType.Post<List<PatientTypeVm>>(new DictPatientTypeQueryRequest
            {
                athenaMenuId = this.context.menuId,
                enabledFlag = "1",
            }).CheckState();
            chooseInsurTypeVm.patientTypeList = gateWayResult.@object;
            if(chooseInsurTypeVm.patientTypeList!=null&& chooseInsurTypeVm.patientTypeList.Count>0)
                chooseInsurTypeVm.selectedPatientType= chooseInsurTypeVm.patientTypeList.FirstOrDefault(f=>f.no== this.context.patientVm.patientTypeNo);
            chooseInsurTypePage = new ChooseInsurTypeFrm();
            (chooseInsurTypePage as ChooseInsurTypeFrm).vm = chooseInsurTypeVm;
            chooseInsurTypePage.DataContext = chooseInsurTypeVm;
            this.framePage = chooseInsurTypePage;

            this.context.cashierMainVm.currentStep.page = new PreCashierFrm(this);
        });

        public override StepHandler stepHandler => new StepHandler(context =>
        {
        });

        public ICommand stepContinue => new RelayCommand(context =>
        {
            if(this.framePage== chooseInsurTypePage)
            {
                ChooseInsurTypeVm chooseInsurTypeVm= (this.framePage as ChooseInsurTypeFrm).vm as ChooseInsurTypeVm;
                if(chooseInsurTypeVm.selectedPatientType==null)
                {
                    MessageBox.Show("未选择患者费别!");
                    return;
                }
                this.context.patientVm.interfaceId = chooseInsurTypeVm.selectedPatientType.interfaceId;
                this.context.patientVm.patientTypeNo = chooseInsurTypeVm.selectedPatientType.no;
                this.context.patientVm.patientTypeDesc = chooseInsurTypeVm.selectedPatientType.name;
            }
            if(this.context.outPreSettlementResponse == null)
            {
                OutSettlementServer outSettlementServer = new OutSettlementServer();
                this.context.outPreSettlementResponse = outSettlementServer.PreSettlement(this.context.outPreSettlementRequest);

                this.context.chargingInfo = new ChargingInfoVm()
                {
                    settlementId = this.context.outPreSettlementResponse.settlementId,
                    amount = this.context.outPreSettlementResponse.amount,
                    discountAmount = this.context.outPreSettlementResponse.discountAmount,
                    encounterId = this.context.outPreSettlementRequest.encounter.encounterId,
                    settlementTypeCode = this.context.outPreSettlementResponse.settlementTypeCode
                };

                try
                {
                    if (!string.IsNullOrEmpty(this.context.patientVm.interfaceId))
                    {
                        InsurServer insurServer = new InsurServer();
                        //查询医保是否需要读卡
                        NeedReadCardResponse needReadCardResponse = insurServer.GetNeedReadCard(new RequestHeader() { interfaceId = long.Parse(this.context.patientVm.interfaceId) }, new NeedReadCardRequest()
                        {
                            currentBizTransactionCoding = this.context.outPreSettlementRequest.settlementTypeCode == "1" ? "101" : "201",
                            patientId = this.context.patientVm.interfaceId,
                            payMtNo = this.context.chargingInfo.settlementId.ToString(),
                            visitNo = this.context.chargingInfo.encounterId.ToString(),
                        });

                        if (needReadCardResponse != null && needReadCardResponse.needReadCardStatus is "1" or "2")
                        {
                            QueryBizSearchComponentListReq req = new QueryBizSearchComponentListReq()
                            {
                                componentCoding = "6",
                                enabledFlag = "1",
                            };
                            BizSearchComponentDubboService bizSearchComponentDubboService = new BizSearchComponentDubboService();
                            var gateWayResult = bizSearchComponentDubboService.queryBizSearchComponentListByCoding.Post<QueryBizSearchComponentListResp>(req).CheckState();
                            if (gateWayResult.@object?.bizSearchTypeList?.Count == 0)
                                throw new SpeedException("读卡组件设置错误!");
                            List<ButtonComponentVm> buttonComponents = new List<ButtonComponentVm>();
                            foreach (var item in gateWayResult.@object.bizSearchTypeList)
                            {
                                buttonComponents.Add(item.CopyProperties<ButtonComponentVm>());
                            }
                            SearchComponentVm searchComponentVm = new SearchComponentVm();
                            searchComponentVm.context = this.context;
                            searchComponentVm.buttonComponents = buttonComponents;
                            searchComponentVm.currBizTradeCode = this.context.outPreSettlementRequest.settlementTypeCode == "1" ? "101" : "201";
                            readCardPage = new SearchComponentFrm(searchComponentVm);
                            this.framePage = readCardPage;
                            return;
                        }

                        string currentBizParams = this.context.outPreSettlementRequest.settlementTypeCode == "1" ? JsonConvert.SerializeObject(new OutRegisterPreviewRequest() { outPayMtNo = this.context.outPreSettlementResponse.settlementId.ToString(), patientId = this.context.patientVm.patientId, visitNo = this.context.outPreSettlementRequest.encounter.encounterId.ToString() }) : JsonConvert.SerializeObject(new OutPayPreviewRequest() { outPayMtNo = this.context.outPreSettlementResponse.settlementId.ToString(), patientId = this.context.patientVm.patientId, visitNo = this.context.outPreSettlementRequest.encounter.encounterId.ToString() });
                        List<DataSelectItemResponse> dataSelectItemResponses = insurServer.InitDataSelectItem(new RequestHeader() { interfaceId = long.Parse(this.context.patientVm.interfaceId), cardInfo = this.context.basicInfo, alreadySelectDataList = this.context.alreadySelectDataList }, new DataSelectItemInitRequest()
                        {
                            currentBizParams = currentBizParams,
                            currentBizTransactionCoding = this.context.outPreSettlementRequest.settlementTypeCode == "1" ? "101" : "201",
                        });

                        if (dataSelectItemResponses != null && dataSelectItemResponses.Count > 0)
                        {
                            DataSelectVm dataSelectVm = new DataSelectVm();
                            dataSelectVm.context = this.context;
                            dataSelectVm.currentBizParams = currentBizParams;
                            dataSelectVm.dataSelectItemList = new List<DataSelectItemVm>();
                            foreach (var item in dataSelectItemResponses)
                            {
                                DataSelectItemVm dataSelectItemVm = item.CopyProperties<DataSelectItemVm>();
                                if (dataSelectItemVm.componentTypeCoding == "1")
                                {
                                    var basicDatas = insurServer.SearchDataSelectItem(new RequestHeader() { interfaceId = long.Parse(this.context.patientVm.interfaceId), cardInfo = this.context.basicInfo, alreadySelectDataList = this.context.alreadySelectDataList }, new DataSelectItemQueryRequest() { basicDataDictTypeId = long.Parse(dataSelectItemVm.basicDataDictTypeId), basicDataDictTypeNo = dataSelectItemVm.basicDataDictTypeNo, currentBizParams = currentBizParams, currentBizTransactionCoding = this.context.outPreSettlementRequest.settlementTypeCode == "1" ? "101" : "201" });
                                    if (basicDatas != null && basicDatas.Count > 0)
                                    {
                                        dataSelectItemVm.basicDataList = new List<BasicDataVm>();
                                        foreach (var data in basicDatas)
                                        {
                                            dataSelectItemVm.basicDataList.Add(new BasicDataVm()
                                            {
                                                basicDataDictTypeId = dataSelectItemVm.basicDataDictTypeId,
                                                basicDataDictTypeNo = dataSelectItemVm.basicDataDictTypeNo,
                                                basicDataExtInfo = data.basicDataExtInfo,
                                                basicDataId = data.basicDataId,
                                                basicDataName = data.basicDataName,
                                                basicDataNo = data.basicDataNo,
                                                pinyin = data.pinyin,
                                                wubi = data.wubi,
                                            });
                                        }
                                        dataSelectItemVm.basicData = dataSelectItemVm.basicDataList.FirstOrDefault(f => f.basicDataId == dataSelectItemVm.basicDataId);
                                    }
                                }
                                dataSelectVm.dataSelectItemList.Add(dataSelectItemVm);
                            }
                            dataSelectPage = new DataSelectFrm();
                            (dataSelectPage as DataSelectFrm).vm = dataSelectVm;
                            dataSelectPage.DataContext = dataSelectVm;
                            this.framePage = dataSelectPage;
                            //this.context.cashierMainVm.localWindow.DataContext = this.context.cashierMainVm;
                            return;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("执行医保交易异常:" + ex.Message);
                    return;
                }
            }
            if (this.framePage == readCardPage)
            {
                try
                {
                    string currentBizParams = this.context.outPreSettlementRequest.settlementTypeCode == "1" ? JsonConvert.SerializeObject(new OutRegisterPreviewRequest() { outPayMtNo = this.context.outPreSettlementResponse.settlementId.ToString(), patientId = this.context.patientVm.patientId, visitNo = this.context.outPreSettlementRequest.encounter.encounterId.ToString() }) : JsonConvert.SerializeObject(new OutPayPreviewRequest() { outPayMtNo = this.context.outPreSettlementResponse.settlementId.ToString(), patientId = this.context.patientVm.patientId, visitNo = this.context.outPreSettlementRequest.encounter.encounterId.ToString() });
                    InsurServer insurServer = new InsurServer();
                    List<DataSelectItemResponse> dataSelectItemResponses = insurServer.InitDataSelectItem(new RequestHeader() { interfaceId = long.Parse(this.context.patientVm.interfaceId), cardInfo = this.context.basicInfo, alreadySelectDataList = this.context.alreadySelectDataList }, new DataSelectItemInitRequest()
                    {
                        currentBizParams = currentBizParams,
                        currentBizTransactionCoding = this.context.outPreSettlementRequest.settlementTypeCode == "1" ? "101" : "201",
                    });

                    if (dataSelectItemResponses != null && dataSelectItemResponses.Count > 0)
                    {
                        dataSelectPage = new DataSelectFrm();
                        this.framePage = dataSelectPage;
                        return;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("执行医保交易异常:" + ex.Message);
                    return;
                }
            }
            if(this.framePage == dataSelectPage)
            {
                var dataSelectVm=(dataSelectPage as DataSelectFrm).vm;
                if(dataSelectVm.dataSelectItemList!=null&& dataSelectVm.dataSelectItemList.Count > 0)
                {
                    this.context.alreadySelectDataList = new List<DataSelectRequest>();
                    foreach (var item in dataSelectVm.dataSelectItemList)
                    {
                        this.context.alreadySelectDataList.Add(new DataSelectRequest()
                        {
                            basicDataDictTypeId = item.basicDataDictTypeId,
                            basicDataDictTypeNo = item.basicDataDictTypeNo,
                            basicDataId = item.basicDataId,
                            basicDataNo = item.basicDataNo,
                            basicDataName = item.basicDataName,
                        });
                    }
                }
            }
            try
            {
                if (this.context.outPreSettlementRequest.settlementTypeCode == "1"&&!string.IsNullOrWhiteSpace(this.context.patientVm.interfaceId))
                {
                    InsurServer insurServer = new InsurServer();
                    var response = insurServer.previewOutRegister(new RequestHeader() { interfaceId = long.Parse(this.context.patientVm.interfaceId), alreadySelectDataList = this.context.alreadySelectDataList }, new OutRegisterPreviewRequest() { outPayMtNo = this.context.outPreSettlementResponse.settlementId.ToString(), patientId = this.context.patientVm.patientId, visitNo = this.context.outPreSettlementRequest.encounter.encounterId.ToString() });
                    this.context.preOutPayResponse = response.CopyProperties<OutPayResponse>();
                    this.context.chargingInfo.insurAmount = response.insurReimAmount;
                }
                else if(this.context.outPreSettlementRequest.settlementTypeCode == "2" && !string.IsNullOrWhiteSpace(this.context.patientVm.interfaceId))
                {
                    InsurServer insurServer = new InsurServer();
                    var response = insurServer.previewOutPay(new RequestHeader() { interfaceId = long.Parse(this.context.patientVm.interfaceId), alreadySelectDataList = this.context.alreadySelectDataList }, new OutPayPreviewRequest() { outPayMtNo = this.context.outPreSettlementResponse.settlementId.ToString(), patientId = this.context.patientVm.patientId, visitNo = this.context.outPreSettlementRequest.encounter.encounterId.ToString() });
                    this.context.preOutPayResponse = response;
                    this.context.chargingInfo.insurAmount = response.insurReimAmount;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("医保预算失败!" + ex.Message);
                return;
            }

            this.context.cashierMainVm.next();
            NoticeChargeResult?.Invoke(this, this.context);
        });

        public ICommand stepCancel => new RelayCommand(context =>
        {
            if (this.context.preOutPayResponse!=null)
            {
                try
                {
                    InsurServer insurServer = new InsurServer();
                    if (this.context.chargingInfo.settlementTypeCode == "1")
                    {
                        insurServer.cancelOutRegisterPreview(new RequestHeader() { interfaceId = long.Parse(this.context.patientVm.interfaceId), alreadySelectDataList = this.context.alreadySelectDataList }, new OutRegisterCancelPreviewRequest() { outPayMtNo = this.context.outPreSettlementResponse.settlementId.ToString(), patientId = this.context.patientVm.patientId, visitNo = this.context.outPreSettlementRequest.encounter.encounterId.ToString() });
                    }
                    else if(this.context.chargingInfo.settlementTypeCode == "2")
                    {
                        insurServer.cancelOutPayPreview(new RequestHeader() { interfaceId = long.Parse(this.context.patientVm.interfaceId), alreadySelectDataList = this.context.alreadySelectDataList }, new OutPayCancelPreviewRequest() { outPayMtNo = this.context.outPreSettlementResponse.settlementId.ToString(), patientId = this.context.patientVm.patientId, visitNo = this.context.outPreSettlementRequest.encounter.encounterId.ToString() });
                    }
                    this.context.chargingInfo.insurAmount = null;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("医保取消预算失败!" + ex.Message);
                }
            }
            NoticeChargeCancel?.Invoke(this, this.context);
        });
    }
}
